home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Imaging / RealShapes / PolyShpe.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  7.6 KB  |  404 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        PolyShpe.cpp
  3.  
  4.     Contains:    Polygon shape class, private to ODShape.
  5.  
  6.     Owned by:    Jens Alfke
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.         <12>     8/18/95    NP        1274946: Remove kODErrInvalidParameter
  13.         <11>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  14.                                     file.
  15.         <10>     5/25/95    jpa        Use new GX headers [1241078, 1253324]
  16.          <9>     3/20/95    jpa        No need to wrap TRY around use of
  17.                                     ODTempPolygon. [1215160
  18.          <8>    12/20/94    jpa        Removed bogus call to Simplify in
  19.                                     InitQDRegion. [1168281]
  20.          <7>     12/5/94    jpa        Removed fSimple; assume client will call
  21.                                     Simplify after SetPolygon. [1191192,
  22.                                     1196018]. Also code-review cleanup
  23.                                     [1203923]
  24.          <6>    10/24/94    jpa        Implemented Outset. [1186719, 1190423].
  25.                                     Added fSimple flag, and simplified before
  26.                                     converting to Region. [1191192]
  27.          <5>     9/29/94    RA        1189812: Mods for 68K build.
  28.          <4>      9/9/94    jpa        Partial implementation of Outset; right now
  29.                                     punts to RgnShape since poly outsetter is
  30.                                     unimplemented. [1178690]
  31.          <3>      8/8/94    jpa        Added Outset method [1178690]
  32.          <2>      8/2/94    jpa        Added no-op case to ::Combine.
  33.          <1>     6/15/94    jpa        first checked in
  34.  
  35.     In Progress:
  36. */
  37.  
  38.  
  39. #ifndef _ALTPOINT_
  40. #include "AltPoint.h"            /* Use C++ savvy ODPoint and ODRect*/
  41. #endif
  42.  
  43. #ifndef _ALTPOLY_
  44. #include "AltPoly.h"
  45. #endif
  46.  
  47. #ifndef _POLYSHPE_
  48. #include "PolyShpe.h"
  49. #endif
  50.  
  51. #ifndef _RECTSHPE_
  52. #include "RectShpe.h"
  53. #endif
  54.  
  55. #ifndef _RGNSHPE_
  56. #include "RgnShpe.h"
  57. #endif
  58.  
  59. #ifndef _EXCEPT_
  60. #include "Except.h"
  61. #endif
  62.  
  63. #ifndef SOM_ODTransform_xh
  64. #include "Trnsform.xh"
  65. #endif
  66.  
  67. #ifndef _RGN2POLY_
  68. #include "Rgn2PlyM.h"
  69. #endif
  70.  
  71. #ifndef _POLYCLIP_
  72. #include "PolyClip.h"
  73. #endif
  74.  
  75. #ifndef _ODDEBUG_
  76. #include "ODDebug.h"
  77. #endif
  78.  
  79. #ifndef _ODMEMORY_
  80. #include "ODMemory.h"
  81. #endif
  82.  
  83. #ifndef _UTILERRS_
  84. #include "UtilErrs.h"
  85. #endif
  86.  
  87. #ifndef __GXGRAPHICS__
  88. #include <GXGraphics.h>
  89. #endif
  90.  
  91.  
  92. PolygonShape::PolygonShape( ODGeometryMode mode )
  93.     :RealShape(mode),
  94.      fPolygon(),
  95.      fBoundsValid(kODFalse)
  96. {
  97. #if ODDebug
  98.     fType = 2;
  99.     WASSERTM(!gGX,"PolygonShape is not worthy: GX installed");
  100. #endif
  101. }
  102.  
  103.  
  104. PolygonShape::~PolygonShape( )
  105. {
  106.     fPolygon.Clear();
  107. }
  108.  
  109.  
  110. ODSize
  111. PolygonShape::Purge( ODSize bytes )
  112. {
  113.     if( bytes==0 )
  114.         fBoundsValid = kODFalse;        // Means just flush cache
  115.     return RealShape::Purge(bytes);
  116. }
  117.  
  118.  
  119. void
  120. PolygonShape::GetBoundingBox( ODRect *bounds )
  121. {
  122.     if( !fBoundsValid )
  123.         fPolygon.ComputeBoundingBox(&fBounds);
  124.     if( bounds )
  125.         *bounds = fBounds;
  126. }
  127.  
  128.  
  129. RealShape*
  130. PolygonShape::SetRectangle( const ODRect *r )
  131. {
  132.     RealShape *rect = new RectShape(fMode,*r);
  133.     delete this;
  134.     return rect;
  135. }
  136.  
  137.  
  138. void
  139. PolygonShape::CopyPolygon( ODPolygon &poly )
  140. {
  141.     poly.CopyFrom(fPolygon);
  142. }
  143.  
  144.  
  145. RealShape*
  146. PolygonShape::SetPolygon( const ODPolygon &poly )
  147. {
  148.     fPolygon.CopyFrom(poly);
  149.     this->Purge(0);
  150.     return this;
  151. }
  152.  
  153.  
  154. void
  155. PolygonShape::Simplify( )
  156. {
  157.     // Client is responsible for calling this method after SetPolygon
  158.     // if the polygon is not known to be simple. PolygonShape assumes
  159.     // its fPolygon is always simple.
  160.     
  161.     PolySimplify(fPolygon,fPolygon);
  162. }
  163.  
  164.  
  165. void
  166. PolygonShape::InitQDRegion( )
  167. {
  168.     RgnHandle rgn = fPolygon.AsQDRegion();
  169.     ODDisposeHandle((ODHandle)fQDRegion);
  170.     fQDRegion = rgn;
  171. }
  172.  
  173.  
  174. gxShape
  175. PolygonShape::CopyGXShape( )
  176. {
  177.     ASSERT(gGX>0,kODErrAssertionFailed);
  178.     return fPolygon.AsGXShape();
  179. }
  180.  
  181.  
  182. ODBoolean
  183. PolygonShape::IsSameAs( RealShape *shape )
  184. {
  185.     if( shape == this )
  186.         return kODTrue;
  187.         
  188.     else if( this->IsEmpty() )
  189.         return shape->IsEmpty();
  190.         
  191.     else if( shape->IsEmpty() )
  192.         return kODFalse;
  193.         
  194.     else if( shape->IsRectangular() )
  195.         if( this->IsRectangular() ) {
  196.             ODRect itsBox;
  197.             this->GetBoundingBox(NULL);
  198.             shape->GetBoundingBox(&itsBox);
  199.             return fBounds==itsBox;
  200.             
  201.         } else
  202.             return kODFalse;
  203.             
  204.     else if( this->IsRectangular() )
  205.         return kODFalse;
  206.         
  207.     else if( shape->HasGeometry() ) {
  208.         ODTempPolygon poly;
  209.         shape->CopyPolygon(poly);
  210.         ODBoolean same;
  211.         same = (fPolygon == poly);
  212.         return same;
  213.         
  214.     } else
  215.         return kODFalse;
  216. }
  217.  
  218.  
  219. ODBoolean
  220. PolygonShape::IsEmpty( )
  221. {
  222.     return fPolygon.IsEmpty();
  223. }
  224.  
  225.  
  226. ODBoolean
  227. PolygonShape::ContainsPoint( ODPoint point )
  228. {
  229.     if( fPolygon.HasData() ) {
  230.         ODRect bbox;
  231.         this->GetBoundingBox(NULL);
  232.         if( !fBounds.Contains(point) )
  233.             return kODFalse;                    // Not in bounding-box
  234.         return fPolygon.Contains(point) != 0;
  235.     } else
  236.         return kODFalse;
  237. }
  238.  
  239.  
  240. ODBoolean
  241. PolygonShape::IsRectangular( )
  242. {
  243.     return fPolygon.IsRectangular();
  244. }
  245.  
  246.  
  247. RealShape*
  248. PolygonShape::Copy( )
  249. {
  250.     PolygonShape *s = new PolygonShape(fMode);
  251.     TRY{
  252.         s->SetPolygon(fPolygon);
  253.     }CATCH_ALL{
  254.         delete s;
  255.         RERAISE;
  256.     }ENDTRY
  257.     return s;
  258. }
  259.  
  260.  
  261. RealShape*
  262. PolygonShape::Transform( Environment *ev, ODTransform *xform )
  263. {
  264.     fPolygon.Transform(ev,xform);
  265.     this->Purge(0);
  266.     return this;
  267. }
  268.  
  269.  
  270. RealShape*
  271. PolygonShape::Outset( ODCoordinate distance )
  272. {
  273.     if( distance!=0 && fPolygon.HasData() ) {
  274.         if( fMode==kODLoseGeometry ) {
  275.             // Convert to QD region:
  276.             RgnHandle rgn = (RgnHandle) ODCopyHandle(
  277.                                 (ODHandle)this->GetPlatformShape(kODQuickDraw) );
  278.             RealShape *s;
  279.             TRY{
  280.                 s = new RgnShape(fMode);
  281.             }CATCH_ALL{
  282.                 DisposeRgn(rgn);
  283.                 RERAISE;
  284.             }ENDTRY
  285.             
  286.             TRY{
  287.                 s->SetPlatformShape(kODQuickDraw,rgn);
  288.                 s = s->Outset(distance);
  289.             }CATCH_ALL{
  290.                 delete s;
  291.                 RERAISE;
  292.             }ENDTRY
  293.             delete this;
  294.             return s;
  295.             
  296.         } else {
  297.             if( PolyOutset(fPolygon,distance) )
  298.                 PolySimplify(fPolygon,fPolygon);
  299.         }
  300.     }
  301.     return this;
  302. }
  303.  
  304.  
  305. RealShape*
  306. PolygonShape::Combine( ODShapeOp op, RealShape *shape )
  307. {
  308.     if( op==kShapeNoOp )
  309.         return this;
  310.     else if( op==kShapeOutset )
  311.     ASSERT(shape!=kODNULL, kODErrIllegalNullInput);
  312.     
  313.     ODPolygon result;
  314.     {
  315.         ODTempPolygon shapePoly;
  316.         shape->CopyPolygon(shapePoly);
  317.     
  318.         ODPolygon* poly[2];
  319.         poly[0] = &fPolygon;
  320.         poly[1] = &shapePoly;
  321.         PolyClip(2,(const ODPolygon**)poly,op, result);
  322.     }
  323.     
  324.     if( result.HasData() ) {
  325.         fPolygon.MoveFrom(result);
  326.         this->Purge(0);
  327.         return this;
  328.     } else
  329.         return this->Clear();
  330. }
  331.  
  332.  
  333. RealShape*
  334. PolygonShape::Subtract( RealShape *shape )
  335. {
  336.     if( shape==this )
  337.         return this->Clear();
  338.     else if( shape->IsEmpty() || this->IsEmpty() )
  339.         return this;
  340.  
  341.     // Check bounding boxes:
  342.     ODRect itsBox;
  343.     this->GetBoundingBox(NULL);
  344.     shape->GetBoundingBox(&itsBox);
  345.     if( !fBounds.Intersects(itsBox) )
  346.         return this;                        // BBoxes do not intersect: no-op
  347.     else if( itsBox.Contains(fBounds) && shape->IsRectangular() )
  348.         return this->Clear();                // shape is a rectangle containing me: clear
  349.     
  350.     if( fMode!=kODLoseGeometry && shape->HasGeometry() )
  351.         return this->Combine(kShapeDifference,shape);
  352.     else
  353.         return this->Promote(kShapeDifference,shape);
  354. }
  355.  
  356.  
  357. RealShape*
  358. PolygonShape::Intersect( RealShape *shape )
  359. {
  360.     if( shape==this || this->IsEmpty() )
  361.         return this;
  362.     else if( shape->IsEmpty() )
  363.         return this->Clear();
  364.     
  365.     // Check bounding boxes:
  366.     ODRect itsBox;
  367.     this->GetBoundingBox(NULL);
  368.     shape->GetBoundingBox(&itsBox);
  369.     if( !fBounds.Intersects(itsBox) )
  370.         return this->Clear();                // BBoxes do not intersect: clear
  371.     else if( itsBox.Contains(fBounds) && shape->IsRectangular() )
  372.         return this;                        // shape is a rectangle containing me: no-op
  373.     
  374.     // OK, must intersect:
  375.     if( fMode!=kODLoseGeometry && shape->HasGeometry() )
  376.         return this->Combine(kShapeIntersection,shape);
  377.     else
  378.         return this->Promote(kShapeIntersection,shape);
  379. }
  380.  
  381.  
  382. RealShape*
  383. PolygonShape::Union( RealShape *shape )
  384. {
  385.     if( shape==this || shape->IsEmpty() )
  386.         return this;
  387.     else if( this->IsEmpty() )
  388.         return this->ReplaceWith(shape);
  389.     
  390.     // Check bounding boxes:
  391.     if( shape->IsRectangular() ) {
  392.         ODRect itsBox;
  393.         this->GetBoundingBox(NULL);
  394.         shape->GetBoundingBox(&itsBox);
  395.         if( itsBox.Contains(fBounds) )
  396.             return this->ReplaceWith(shape);
  397.     }
  398.     
  399.     if( fMode!=kODLoseGeometry && shape->HasGeometry() )
  400.         return this->Combine(kShapeUnion,shape);
  401.     else
  402.         return this->Promote(kShapeUnion,shape);
  403. }
  404.